package com.iwuyc.tools.commons.util.guava;

import com.google.common.base.Stopwatch;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.event.Level;

import java.util.Collections;
import java.util.EnumMap;
import java.util.Map;

/**
 * 用时记录者
 *
 * @author 吴宇春
 * @version 1.0.0
 * @since 2023-05-30
 */
@Slf4j
public class ElapsedWatcherPrinter implements AutoCloseable {
    private static final Map<Level, LogPrinter> LOG_PRINTER_BY_LEVEL;

    static {
        final Map<Level, LogPrinter> temp = new EnumMap<>(Level.class);
        temp.put(Level.TRACE, log::trace);
        temp.put(Level.DEBUG, log::debug);
        temp.put(Level.INFO, log::info);
        temp.put(Level.ERROR, log::error);
        LOG_PRINTER_BY_LEVEL = Collections.unmodifiableMap(temp);
    }

    private final String taskName;
    private final Stopwatch stopwatch = Stopwatch.createStarted();
    private final LogPrinter logPrinter;

    private ElapsedWatcherPrinter(String taskName, Level level) {
        this.taskName = taskName;
        this.logPrinter = LOG_PRINTER_BY_LEVEL.getOrDefault(level, log::debug);
    }

    public static ElapsedWatcherPrinter create() {
        return create("default", Level.DEBUG);
    }

    public static ElapsedWatcherPrinter create(String taskName) {
        return create(taskName, Level.DEBUG);
    }

    public static ElapsedWatcherPrinter create(String taskName, Level level) {
        return new ElapsedWatcherPrinter(taskName, level);
    }

    public void elapsed() {
        elapsed("default");
    }

    public void elapsed(String tag) {
        this.logPrinter.print("任务：{}；tag：{}；已耗时：{}", new Object[]{taskName, tag, this.stopwatch.elapsed()});
    }

    @Override
    public void close() {
        this.logPrinter.print("任务：{}；总耗时：{}", new Object[]{taskName, this.stopwatch.stop()});
    }

    private interface LogPrinter {
        void print(String message, Object[] arguments);
    }

}
